package com.xquant.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xquant.system.entity.TimpSignTest;
import com.xquant.system.entity.TwcBndDefaultCompareTest;
import com.xquant.system.entity.VwcBndDefault;
import com.xquant.system.enums.DataSourceEnum;
import com.xquant.system.enums.SetSameEnum;
import com.xquant.system.exception.ServiceException;
import com.xquant.system.mapper.VwcBndDefaultMapper;
import com.xquant.system.service.TimpSignTestService;
import com.xquant.system.service.TwcBndDefaultCompareTestService;
import com.xquant.system.service.VwcBndDefaultService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import java.text.SimpleDateFormat;
import java.util.*;
import static com.xquant.system.common.DataStatus.DATA_STATUS_DIFF;
import static com.xquant.system.common.DataStatus.DATA_STATUS_PASS;
import static com.xquant.system.common.ResultCode.NO_INCREMENT_DATA;


/**
 * @author 04641
 * @description 针对表【VWC_BND_DEFAULT】的数据库操作Service实现
 * 将三方数据来源为同一债券的数据按照字段维度对比出差异
 * @createDate 2023-09-06 10:16:15
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class VwcBndDefaultServiceImpl extends ServiceImpl<VwcBndDefaultMapper, VwcBndDefault>
        implements VwcBndDefaultService {

    @Autowired
    private VwcBndDefaultMapper vwcBndDefaultMapper;

    @Autowired
    private TwcBndDefaultCompareTestService twcBndDefaultCompareTestService;

    @Autowired
    private TimpSignTestService timpSignTestService;


    @Override
    public Boolean threeWayComparison(){

        //接收比对结果
        List<TwcBndDefaultCompareTest> twcBndDefaultCompareTestsList;
        //先做增量判断
        QueryWrapper<TimpSignTest> timpSignTestQueryWrapper = new QueryWrapper<>();
        timpSignTestQueryWrapper.eq("DEST_TABLE", "TWC_BND_DEFAULT_TEST_SIGN");
        //判断增量表中是否有数据
        TimpSignTest timpSignTest = timpSignTestService.getOne(timpSignTestQueryWrapper);
        //增量表中没有数据
        if (timpSignTest == null) {
            //创建增量表数据
            TimpSignTest timpSignTestNew = new TimpSignTest();
            //查询全量视图表
            List<VwcBndDefault> vwcBndDefaults = this.list();
            //比对结果
            twcBndDefaultCompareTestsList = compareField(vwcBndDefaults);

            //获取最大的导入时间
            vwcBndDefaults.stream().filter(Objects::nonNull)
                    .max(Comparator.comparing(VwcBndDefault::getImpTime))
                    .ifPresent(s -> timpSignTestNew.setMaxId(s.getImpTime()));
            timpSignTestNew.setDestTable("TWC_BND_DEFAULT_TEST_SIGN");
            timpSignTestNew.setDestName("TWC_BND_DEFAULT_TEST_SIGN");
            timpSignTestNew.setPipeId(1L);
            timpSignTestNew.setVarName("TWC_BND_DEFAULT_TEST_SIGN");
            timpSignTestNew.setUpdateTime(new Date());
            //保存增量表
            timpSignTestService.save(timpSignTestNew);
        } else {
            //上次更新时间
            String MaxId = timpSignTest.getMaxId();

            QueryWrapper<VwcBndDefault> vwcBndDefaultQueryWrapper = new QueryWrapper<>();
            vwcBndDefaultQueryWrapper.gt("IMP_TIME", MaxId);
            List<VwcBndDefault> vwcBndDefaults = vwcBndDefaultMapper.selectList(vwcBndDefaultQueryWrapper);
            if (vwcBndDefaults.size() == 0) {
                throw new ServiceException(NO_INCREMENT_DATA,"没有增量数据");
            }

            twcBndDefaultCompareTestsList = compareField(vwcBndDefaults);
            //更新增量表 最大导入时间
            timpSignTest.setLastMaxId(timpSignTest.getMaxId());
            vwcBndDefaults.stream().filter(Objects::nonNull)
                    .max(Comparator.comparing(VwcBndDefault::getImpTime))
                    .ifPresent(s -> timpSignTest.setMaxId(s.getImpTime()));

            timpSignTest.setUpdateTime(new Date());
            timpSignTestService.update(timpSignTest, new QueryWrapper<TimpSignTest>().eq("DEST_TABLE", "TWC_BND_DEFAULT_TEST_SIGN"));

        }
        return twcBndDefaultCompareTestService.saveBatch(twcBndDefaultCompareTestsList);


    }

    /**
     * 数据对比 比对债券数据是否有差异
     * @param vwcBndDefaults
     * @return
     */
    public static List<TwcBndDefaultCompareTest> compareField(List<VwcBndDefault> vwcBndDefaults) {
        //flag为true时，表示三方债券没有差异
        Boolean flag = true;
        List<TwcBndDefaultCompareTest> twcBndDefaultCompareTestsHtWdCh = new ArrayList<>();
        Date date = new Date();
        SimpleDateFormat formatterDte = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat formatterTime = new SimpleDateFormat("HH:mm:ss");

        for (VwcBndDefault vwcBndDefault : vwcBndDefaults) {

            //将转化为一组数据不需要对比的数据提取出来
            TwcBndDefaultCompareTest twcBndDefaultCompareTest = TwcBndDefaultCompareTest(vwcBndDefault, formatterTime, date, formatterDte);

            //将vwcBndDefault转化为map 属性名作为key 值作为value
            Map<String, Object> vwcBndDefaultMap = BeanUtil.beanToMap(vwcBndDefault);

            //用-分割数据来源
            String[] keywords = vwcBndDefault.getDataSources().split("-");

            //判断数据来源 数据源组合
            HtChWdDataSets(twcBndDefaultCompareTest, vwcBndDefault);

            SetSameEnum[] values = SetSameEnum.values();
            for (SetSameEnum value : values) {
                Set<Object> objectset = new HashSet<>();
                for (String keyword : keywords) {
                    //将数据源和关键字拼接 拼接为属性名
                    objectset.add(vwcBndDefaultMap.get(value.getValue() + keyword));
                }
                //判断三方债券数据是否一致并且判断第一个数据源为HT
                if (objectset.size() == 1 && "HT".equals(keywords[0])) {

                    String s = ObjectUtils.isEmpty(vwcBndDefaultMap.get(value.getValue() + keywords[0]))
                            ? null: vwcBndDefaultMap.get(value.getValue() + keywords[0]).toString();
                    compareDataHtWdCh(value, twcBndDefaultCompareTest, s);
                } else {
                    compareDataHtWdCh(value, twcBndDefaultCompareTest, "Diff");
                    flag = false;
                }
            }
            //判断数据状态对比
            if (flag) {
                twcBndDefaultCompareTest.setDataStatus(Long.valueOf(DATA_STATUS_PASS));
            } else {
                twcBndDefaultCompareTest.setDataStatus(Long.valueOf(DATA_STATUS_DIFF));
            }
            twcBndDefaultCompareTestsHtWdCh.add(twcBndDefaultCompareTest);
        }
        return twcBndDefaultCompareTestsHtWdCh;
    }

    /**
     * 比对后属性设置
     * */
        private static void compareDataHtWdCh(SetSameEnum setSameFile, TwcBndDefaultCompareTest twcBndDefaultCompareTest, String value) {

        switch (setSameFile) {
            case NAME:
                //设置债券简称
                twcBndDefaultCompareTest.setName(value);
                break;
            case TRANSACTION_CODE:
                //设置债券代码
                twcBndDefaultCompareTest.setiCode(value);
                break;
            case TRADING_MARKETS:
                //设置债券市场
                twcBndDefaultCompareTest.setmType(value);
                break;
            case DEFAULT_TYPE:
                //设置违约类型
                twcBndDefaultCompareTest.setDefaultType(value);
                break;
            case EVENT_DEFAULT:
                //设置违约事件
                twcBndDefaultCompareTest.setDefaultEvent(value);
                break;
            case DEFAULT_AMOUNT_TOTAL:
                //设置违约总金额
                twcBndDefaultCompareTest.setDefaultAmount(value);
                break;
            case DEFAULT_AMOUNT:
                //设置违约本金
                twcBndDefaultCompareTest.setDefaultNotional(value);
                break;
            case DEFAULT_INTEREST:
                //设置违约利息
                twcBndDefaultCompareTest.setDefaultInt(value);
                break;
        }
    }

    /**
     * 判断 数据源组合 数据来源
     * */
    public static void HtChWdDataSets(TwcBndDefaultCompareTest twcBndDefaultCompareTest, VwcBndDefault vwcBndDefault) {
        DataSourceEnum[] values = DataSourceEnum.values();
        boolean flag = true;
        for (DataSourceEnum value : values) {
            if (value.getValue().equals(vwcBndDefault.getDataSources())) {
                //设置数据源组合
                twcBndDefaultCompareTest.setDataStatusSrc(value.getDescription());
                //设置数据源
                twcBndDefaultCompareTest.setDataSources(vwcBndDefault.getDataSources());
                flag = false;
                continue;
            }
        }
        if (flag) {
            //都不满足 则为DATA_SOURCE_ONE
            twcBndDefaultCompareTest.setDataStatusSrc(DataSourceEnum.DATA_SOURCE_ONE.getDescription());
            twcBndDefaultCompareTest.setDataSources(vwcBndDefault.getDataSources());
        }

    }

    /**
     * 将转化为一组数据不需要对比的数据提取出来
     * */
    private static TwcBndDefaultCompareTest TwcBndDefaultCompareTest(VwcBndDefault vwcBndDefault, SimpleDateFormat formatterTime, Date date, SimpleDateFormat formatterDte) {
        TwcBndDefaultCompareTest twcBndDefaultCompareTest = new TwcBndDefaultCompareTest();
        //导入日期
        twcBndDefaultCompareTest.setImpTime(vwcBndDefault.getImpTime());
        //违约日期
        twcBndDefaultCompareTest.setDefaultDate(vwcBndDefault.getDefaultDate());
        //更新时间
        twcBndDefaultCompareTest.setUpdateTime(formatterTime.format(date));
        //更新日期
        twcBndDefaultCompareTest.setUpdateDate(formatterDte.format(date));
        //联合主键SEC_CODE
        twcBndDefaultCompareTest.setSecCode(vwcBndDefault.getSecCode());
        twcBndDefaultCompareTest.setdCode(vwcBndDefault.getDCode());
        twcBndDefaultCompareTest.setIsexist("1");
        //修改时间
        twcBndDefaultCompareTest.setUpdatedTime(date);

        //维护日期
        twcBndDefaultCompareTest.setImpDate(formatterDte.format(date));
        return twcBndDefaultCompareTest;
    }
}





